package com.xdd.dao.config.db;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public abstract class AbstractDbConfig
{
	protected static final Logger logger = LoggerFactory.getLogger(AbstractDbConfig.class);

	protected StatFilter statFilter(AbstractResourceConfig dbServerConfig)
	{
		StatFilter filter = new StatFilter();
		System.out.println("---------"+dbServerConfig);
		filter.setLogSlowSql(dbServerConfig.getLogSlowSql());
		filter.setSlowSqlMillis(dbServerConfig.getSlowSqlMillis());
		filter.setMergeSql(dbServerConfig.getMergeSql());
		return filter;
	}

	protected Slf4jLogFilter Slf4jFilter(AbstractResourceConfig dbServerConfig)
	{
		Slf4jLogFilter filter = new Slf4jLogFilter();
		filter.setDataSourceLogEnabled(dbServerConfig.getDataSourceLogEnabled());
		filter.setConnectionLogEnabled(dbServerConfig.getConnectionLogEnabled());
		filter.setConnectionLogErrorEnabled(dbServerConfig.getConnectionLogErrorEnabled());
		filter.setStatementLogEnabled(dbServerConfig.getStatementLogEnabled());
		filter.setStatementLogErrorEnabled(dbServerConfig.getStatementLogErrorEnabled());
		filter.setResultSetLogEnabled(dbServerConfig.getResultSetLogEnabled());
		filter.setResultSetLogErrorEnabled(dbServerConfig.getResultSetLogErrorEnabled());
		return filter;
	}

	protected DruidDataSource dataSource(AbstractResourceConfig dbServerConfig, StatFilter statFilter,
                                         Slf4jLogFilter log4j2Filter)
			throws SQLException
	{
		DruidDataSource druidDataSource = new DruidDataSource();
		druidDataSource.setName(dbServerConfig.getDsName());
		druidDataSource.setDriverClassName(dbServerConfig.getDriverClassName());
		druidDataSource.setUrl(dbServerConfig.getUrl());
		druidDataSource.setUsername(dbServerConfig.getUser());
		druidDataSource.setPassword(dbServerConfig.getPassword());
		druidDataSource.setInitialSize(dbServerConfig.getInitialSize());
		druidDataSource.setMinIdle(dbServerConfig.getMinIdle());
		druidDataSource.setMaxActive(dbServerConfig.getMaxActive());
		druidDataSource.setValidationQuery(dbServerConfig.getValidationQuery());
		druidDataSource.setTestOnBorrow(false);
		druidDataSource.setTestOnReturn(false);
		druidDataSource.setTestWhileIdle(true);
		druidDataSource.setTimeBetweenEvictionRunsMillis(60000L);
		druidDataSource.setMaxEvictableIdleTimeMillis(93600000L);
		druidDataSource
				.setPoolPreparedStatements(dbServerConfig.getPoolPreparedStatements());
		druidDataSource
				.setMaxOpenPreparedStatements(dbServerConfig.getMaxOpenPreparedStatements());

		druidDataSource
				.setTimeBetweenLogStatsMillis(dbServerConfig.getTimeBetweenLogStatsMillis());
		List<Filter> filters = new ArrayList<>();
		filters.add(log4j2Filter);
		filters.add(statFilter);
		druidDataSource.setProxyFilters(filters);
		if (dbServerConfig.getUseUtf8mb4Connection())
		{
			druidDataSource.setConnectionInitSqls(Arrays.asList("SET NAMES 'utf8mb4'"));
		}
		return druidDataSource;
	}

	protected SqlSessionFactory sqlSessionFactory(DruidDataSource dataSource) throws Exception
	{
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mappers/*/*.xml"));
		sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
		return sqlSessionFactoryBean.getObject();
	}

	protected SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory)
	{
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	protected PlatformTransactionManager transactionManager(DruidDataSource dataSource)
			throws SQLException
	{
		return new DataSourceTransactionManager(dataSource);
	}
}